﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Clandestine;

namespace Slick.MapEditor
{

    public delegate void LayerAddDelegate(Layer l);
    public delegate void LayerDeleteDelegate(int id);
    public delegate void LayersClearedDelegate();

    public class LayerManager
    {
        public List<Layer> Layers = new List<Layer>();
        public Layer TempLayer = new Layer();

        public Layer this[int index]
        {
            get
            {
                return Layers[index];
            }
        }

        private int selectedLayerID = 0;
        public int SelectedLayerID
        {
            get { return selectedLayerID; }
            set 
            {
                lock (Layers)
                {
                    if (ShowOnlyCurrent)
                        Layers[selectedLayerID].HideEverything();
                    selectedLayerID = value;
                    if (ShowOnlyCurrent)
                        Layers[selectedLayerID].ShowEverything();
                }
            }
        }

        public Layer SelectedLayer
        {
            get
            {
                lock (Layers)
                    return Layers[SelectedLayerID];
            }
        }

        private bool showOnlyCurrent = false;
        public bool ShowOnlyCurrent
        {
            get { return showOnlyCurrent; }
            set
            {
                lock (Layers)
                {
                    showOnlyCurrent = value;

                    foreach (Layer l in Layers)
                        if (value)
                            l.HideEverything();
                        else
                            l.ShowEverything();

                    Layers[SelectedLayerID].ShowEverything();
                }
            }
        }

        public event LayerAddDelegate OnLayerAdd;
        public event LayerDeleteDelegate OnLayerDelete;
        public event LayersClearedDelegate OnLayersCleared;

        public void Add(decimal depth)
        {   
            Layer l = new Layer();
            l.Depth = depth;
            Add(l);
        }
        public void Add(Layer layer)
        {
            lock (Layers)
            {
                layer.ID = Layers.Count;
                Layers.Add(layer);
            }

            // Tell the GUI/Anything else
            // Useful, even if the GUI requested the add for things like opening levels etc.
            if (OnLayerAdd != null)
                OnLayerAdd(layer);
        }

        public void Delete(Layer l)
        {
            Delete(l.ID);
        }
        public void Delete(int id)
        {
            // Check we aren't deleting the last layer
            if (Layers.Count == 1)
                throw new ArgumentException("Can't delete the last layer!");

            // Delete it
            lock (Layers)
            {
                Layers[id].Dispose();
                Layers.Remove(Layers[id]);
            }

            // Fire event for GUI
            if (OnLayerDelete != null)
                OnLayerDelete(id);
        }

        public void CloneLayer(Layer l, decimal depth)
        {
            CloneLayer(l.ID, depth);
        }
        public void CloneLayer(int id, decimal depth)
        {
            lock (Layers)
                Add(Layers[id].Clone(depth));
        }

        public void Clear()
        {
            lock (Layers)
            {
                // Delete each layer
                foreach (Layer l in Layers)
                {
                    int id = l.ID; // don't like firing event before the deletion!
                    l.Dispose();
                    //OnLayerDelete(id);  // HACOUGH
                    OnLayersCleared();
                }
                Layers.Clear(); // empty list

                TempLayer.Dispose();
                TempLayer = new Layer();
            }
        }

        public void ResetTempLayer()
        {
            lock (Layers)
                TempLayer.ClearAllTiles();
            //TempLayer.HideEverything();
            //tempLayer.Dispose(); // actually just resets it, we cool bro
        }
    }
}
